package car_search

import (
	"car-thirdparty-api/internal/consts"
	"car-thirdparty-api/internal/dao"
	"car-thirdparty-api/internal/model"
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"sort"
	"sync"

	"car-thirdparty-api/api/car_search/v1"
)

func (c *ControllerV1) CarSearch(ctx context.Context, req *v1.CarSearchReq) (res *v1.CarSearchRes, err error) {
	resData := make([]*model.CarSearchItem, 0)
	var wg sync.WaitGroup
	wg.Add(4)
	go c.queryCard(ctx, req.Plate, &resData, &wg)
	go c.queryCardOnline(ctx, req.Plate, &resData, &wg)
	go c.queryOrder(ctx, req.Plate, &resData, &wg)
	//go queryTempOnline(ctx, req.Plate, resData, &wg)
	go c.queryBlackList(ctx, req.Plate, &resData, &wg)
	wg.Wait()

	// 根据Age字段进行排序
	sort.Slice(resData, func(i, j int) bool {
		return resData[i].DataType < resData[j].DataType
	})

	res = new(v1.CarSearchRes)
	res.List = resData
	res.Total = len(resData)
	return
}

func (c *ControllerV1) queryCard(ctx context.Context, plate string, list *[]*model.CarSearchItem, wg *sync.WaitGroup) (resData *model.CarSearchItem) {
	var cardList []*model.CardSearch

	err := dao.Card.Ctx(ctx).
		WhereLike(dao.Card.Columns().CarNum, "%"+plate+"%").
		Where(dao.Card.Columns().StartTime+" <= ?", gtime.Now()).
		Where(dao.Card.Columns().EndTime+" >= ?", gtime.Now()).
		WhereNotIn(dao.Card.Columns().Flag, []int{3, 13}).
		OrderDesc(dao.Card.Columns().CreateTime).
		//Limit(1).
		Scan(&cardList)
	if err != nil {
		g.Log().Error(ctx, "查询办证信息失败, ", err)
	}

	if len(cardList) > 0 {
		// 动态关联查询人员信息和部门信息
		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "JobId")).
			ScanList(&cardList, "BUser", "Card", "user_name:JobId")
		if err != nil {
			return nil
		}

		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "CreateBy")).
			ScanList(&cardList, "CUser", "Card", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "UpdateBy")).
			ScanList(&cardList, "UUser", "Card", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(cardList, "DeptId")).
			ScanList(&cardList, "Dept", "Card", "dept_id:DeptId")
		if err != nil {
			return nil
		}

		for _, card := range cardList {
			resData = &model.CarSearchItem{
				CarNum:    card.CarNum,
				DataType:  consts.Card,
				Identity:  card.CarId,
				Name:      card.CardName,
				PhoneNum:  card.CardTel,
				JobId:     card.JobId,
				StartTime: card.StartTime.Format(consts.DateFormat),
				EndTime:   card.EndTime.Format(consts.DateFormat),
			}
			if card.BUser != nil {
				resData.BUserName = card.BUser.NickName
			}
			if card.CUser != nil {
				resData.CUserName = card.CUser.NickName
			}
			if card.UUser != nil {
				resData.UUserName = card.UUser.NickName
			}
			if card.Dept != nil {
				resData.DeptName = card.Dept.DeptName
			}
			*list = append(*list, resData)
		}
	}
	g.Log().Debug(ctx, "查询办证信息成功，done")
	wg.Done()
	return
}

// 查询月租车信息表
func (c *ControllerV1) queryCardOnline(ctx context.Context, plate string, list *[]*model.CarSearchItem, wg *sync.WaitGroup) (resData *model.CarSearchItem) {
	var cardOnlineList []*model.CardOnlineSearch
	err := dao.CardOnline.Ctx(ctx).
		WhereLike(dao.CardOnline.Columns().CarNum, "%"+plate+"%").
		Where(dao.CardOnline.Columns().StartTime+" <= ?", gtime.Now()).
		Where(dao.CardOnline.Columns().EndTime+" >= ?", gtime.Now()).
		OrderDesc(dao.CardOnline.Columns().CreateTime).
		Scan(&cardOnlineList)
	if err != nil {
		g.Log().Error(ctx, "查询月租车信息失败, ", err)
	}

	if len(cardOnlineList) > 0 {
		// 动态关联查询人员信息和部门信息
		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardOnlineList, "CreateBy")).
			ScanList(&cardOnlineList, "CUser", "CardOnline", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardOnlineList, "UpdateBy")).
			ScanList(&cardOnlineList, "UUser", "CardOnline", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(cardOnlineList, "DeptId")).
			ScanList(&cardOnlineList, "Dept", "CardOnline", "dept_id:DeptId")
		if err != nil {
			return nil
		}

		for _, cardOnline := range cardOnlineList {
			resData = &model.CarSearchItem{
				CarNum:     cardOnline.CarNum,
				DataType:   consts.CardOnline,
				Identity:   cardOnline.CardIdNum,
				Name:       cardOnline.CardName,
				PhoneNum:   cardOnline.CardTel,
				StartTime:  cardOnline.StartTime.Format(consts.DateFormat),
				EndTime:    cardOnline.EndTime.Format(consts.DateFormat),
				ExpireTime: cardOnline.ExpDate.Format(consts.DateFormat),
			}

			if cardOnline.CUser != nil {
				resData.CUserName = cardOnline.CUser.NickName
			}
			if cardOnline.UUser != nil {
				resData.UUserName = cardOnline.UUser.NickName
			}
			if cardOnline.Dept != nil {
				resData.DeptName = cardOnline.Dept.DeptName
			}
			*list = append(*list, resData)
		}
	}
	g.Log().Debug(ctx, "查询月租信息成功，done")
	wg.Done()
	return
}

// 查询预约车信息表
func (c *ControllerV1) queryOrder(ctx context.Context, plate string, list *[]*model.CarSearchItem, wg *sync.WaitGroup) (resData *model.CarSearchItem) {
	var bookingCardList []*model.BookingCardSearch
	err := dao.BookingCard.Ctx(ctx).
		WhereLike(dao.BookingCard.Columns().CarNum, "%"+plate+"%").
		Where(dao.BookingCard.Columns().OrderStartTime+" <= ?", gtime.Now()).
		Where(dao.BookingCard.Columns().OrderEndTime+" >= ?", gtime.Now()).
		OrderDesc(dao.BookingCard.Columns().CreateTime).
		Scan(&bookingCardList)
	if err != nil {
		g.Log().Error(ctx, "查询预约车信息失败, ", err)
	}

	if len(bookingCardList) > 0 {

		// 动态关联查询人员信息和部门信息
		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(bookingCardList, "CreateBy")).
			ScanList(&bookingCardList, "CUser", "BookingCard", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(bookingCardList, "UpdateBy")).
			ScanList(&bookingCardList, "UUser", "BookingCard", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(bookingCardList, "DeptId")).
			ScanList(&bookingCardList, "Dept", "BookingCard", "dept_id:DeptId")
		if err != nil {
			return nil
		}

		for _, bookingCard := range bookingCardList {
			resData = &model.CarSearchItem{
				CarNum:    bookingCard.CarNum,
				DataType:  consts.BookingCard,
				Identity:  "",
				Name:      bookingCard.OrderUser,
				PhoneNum:  bookingCard.OrderTel,
				StartTime: bookingCard.OrderStartTime.Format(consts.DateFormat),
				EndTime:   bookingCard.OrderEndTime.Format(consts.DateFormat),
			}

			if bookingCard.CUser != nil {
				resData.CUserName = bookingCard.CUser.NickName
			}
			if bookingCard.UUser != nil {
				resData.UUserName = bookingCard.UUser.NickName
			}
			if bookingCard.Dept != nil {
				resData.DeptName = bookingCard.Dept.DeptName
			}
			*list = append(*list, resData)
		}
	}
	g.Log().Debug(ctx, "查询预约信息成功，done")
	wg.Done()
	return
}

// 查询临时车包月信息表
func (c *ControllerV1) queryTempOnline(ctx context.Context, plate string, list *[]*model.CarSearchItem, wg *sync.WaitGroup) (resData *model.CarSearchItem) {
	var tempOnlineList []*model.TempOnlineSearch
	err := dao.TempOnline.Ctx(ctx).
		WhereLike(dao.TempOnline.Columns().CarNum, "%"+plate+"%").
		Where(dao.TempOnline.Columns().StartTime+" <= ?", gtime.Now()).
		Where(dao.TempOnline.Columns().EndTime+" >= ?", gtime.Now()).
		OrderDesc(dao.TempOnline.Columns().CreateTime).
		Scan(&tempOnlineList)
	if err != nil {
		g.Log().Error(ctx, "查询临时车包月信息失败, ", err)
	}

	if len(tempOnlineList) > 0 {
		// 动态关联查询人员信息和部门信息
		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(tempOnlineList, "CreateBy")).
			ScanList(&tempOnlineList, "CUser", "TempOnline", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(tempOnlineList, "UpdateBy")).
			ScanList(&tempOnlineList, "UUser", "TempOnline", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(tempOnlineList, "DeptId")).
			ScanList(&tempOnlineList, "Dept", "TempOnline", "dept_id:DeptId")
		if err != nil {
			return nil
		}

		for _, tempOnline := range tempOnlineList {
			resData = &model.CarSearchItem{
				CarNum:     tempOnline.CarNum,
				DataType:   consts.TempOnline,
				Identity:   tempOnline.CardIdNum,
				Name:       tempOnline.CardName,
				PhoneNum:   tempOnline.CardTel,
				StartTime:  tempOnline.StartTime.Format(consts.DateFormat),
				EndTime:    tempOnline.EndTime.Format(consts.DateFormat),
				ExpireTime: tempOnline.ExpDate.Format(consts.DateFormat),
			}
			if tempOnline.CUser != nil {
				resData.CUserName = tempOnline.CUser.NickName
			}
			if tempOnline.UUser != nil {
				resData.UUserName = tempOnline.UUser.NickName
			}
			if tempOnline.Dept != nil {
				resData.DeptName = tempOnline.Dept.DeptName
			}
			*list = append(*list, resData)
		}
	}
	g.Log().Debug(ctx, "查询外部车包月信息成功，done")
	wg.Done()
	return
}

// 查询黑名单信息表
func (c *ControllerV1) queryBlackList(ctx context.Context, plate string, list *[]*model.CarSearchItem, wg *sync.WaitGroup) (resData *model.CarSearchItem) {
	var blackListList []*model.BlackListSearch
	err := dao.BlackListRecord.Ctx(ctx).
		WhereLike(dao.BlackListRecord.Columns().CarNum, "%"+plate+"%").
		OrderDesc(dao.BlackListRecord.Columns().CreateTime).
		Scan(&blackListList)
	if err != nil {
		g.Log().Error(ctx, "查询黑名单信息失败, ", err)
	}

	if len(blackListList) > 0 {
		// 动态关联查询人员信息和部门信息
		err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(blackListList, "CreateBy")).
			ScanList(&blackListList, "CUser", "BlackListRecord", "user_name:CreateBy")
		if err != nil {
			return nil
		}

		for _, blackList := range blackListList {
			resData = &model.CarSearchItem{
				CarNum:   blackList.CarNum,
				DataType: consts.BlackList,
				Identity: "",
				Name:     "",
				PhoneNum: "",
			}
			if blackList.CUser != nil {
				resData.CUserName = blackList.CUser.NickName
			}

			*list = append(*list, resData)
		}
	}
	g.Log().Debug(ctx, "查询黑名单信息成功，done")
	wg.Done()
	return
}
